SSO 的 solution 有許多種,IT 邦幫忙本身也已有 SSO 的機制,
好像是去年 Blog 改版的同時啟用,整合的完美而感覺不出來,至於是用哪一種?就不得而知了。
敝單位也有需要 SSO 的機制,最常被廠商建議的是 IBM的Solution;
這樣似乎就得用 IBM Tivoli 相關的產品。
沒那麼多的經費就自行試試如何實作。
在Ruby裡早已有 RubyCAS-Server 的 SSO 的套件,其架構如圖:
網路上的建制步驟資料,寫得好像蠻簡單,
但進行過程的錯誤嘗試後,
相關細節,只有跑過一遍才會留意到,
在此趕緊記錄一下。
安裝設定 RubyCAS-Server
0.以 casserver.company.com 做 CAS server。
ruby 1.9.x 無法跑,要解決的力氣,不如再裝 ruby 1.8.x。
1.1 Fedora12、Ubuntu 10.04 預設是裝 ruby 1.8.x 所以免煩惱此問題。
1.2 ArchLinux 預設裝 ruby 1.9.1,而要加裝 ruby1.8 才動得起來。
執行 gem install rubycas-server
rubycas-server 本身是架構在 picnic 小型framework上,
可用的 webserver 是 webrick 或 mongrel,後者效能較前者好。thin 跑不起來。
用 mongrel 也有些待解決的問題,所以先用預設的 webrick 跑。
用 root 執行 rubycas-server 會產生 /etc/rubycas-server/config.yml 設定檔,然後修改成適自己的環境。
...
server: webrick
port: 443
ssl_cert: /etc/rubycas-server/server.crt
ssl_key: /etc/rubycas-server/server.key
...
database:
adapter: sqlite3
dbfile: /etc/rubycas-server/casserver.db
...
authenticator:
class: CASServer::Authenticators::SQL
database:
adapter: sqlite3
database: /etc/rubycas-server/casserver.db
user_table: users
username_column: username
password_column: password
4.產生 SSL 所需的 Private Key, CSR (Certificate Signing Request), Self-Signed Certificate。來供上述的ssl_cert, ssl_key所用。
參閱 Generating an SSL Certificate with Apache+mod_ssl 的指令:
cd /etc/rubycas-server
openssl genrsa -des3 -rand file1:file2:file3:file4:file5 -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 360 -in server.csr -signkey server.key -out server.crt
5.建立資料庫及認證用的 table、再建個帳號密碼來測試:
sqlite3 casserver.db
CREATE TABLE users(username varchart(32), password varchart(32));
insert into 'users' ('username', 'password') values ('test1','test1pass');
6.執行 rubycas-server,由於自建 crt,需打一次 server.key 的密碼,才會繼續跑,
(不曉得怎樣才能自動跑?用購買的安全憑證就不需密碼嗎?)如果執行成功的話,
https://casserver.company.com/ 就可連到認證畫面,
試試用剛鍵的帳密是否認證成功,/logout 可結束此 ticket。
若執行失敗,看是錯誤訊息來改設定檔或裝所需要的gem。
在 RoR 安裝 rubycas-client
0.以 host1.company.com 做 CAS client。
1.參閱:rubycas-client 的安裝設定步驟。
2.在 rails 的 project 中執行:script/plugin install http://rubycas-client.googlecode.com/svn/trunk/rubycas-client
以 plugin 的方式來安裝,方便修改後續會碰到的問題。
3.在 config/environment.rb 最底下加入:
require 'casclient'
require 'casclient/frameworks/rails/filter'
CASClient::Frameworks::Rails::Filter.configure(
:cas_base_url => "https://casserver.company.com/"
)
4.以下設定及相關變數是較會用到的,
詳細設定參閱http://rubycas-client.rubyforge.org/
#在 Controller 上定義哪些 action 需要或不需要 cas 的認證:
before_filter CASClient::Frameworks::Rails::Filter, :except => [ :index, :logout ]
# 抓已認證過的帳號名稱
@username = session[:cas_user]
5.同樣需要 sso 的 client 依此方式建立host2,3,...,
也可以用 php, python 等來建 cas 的 client。
上述是依相關文件的主要建置過程,就應可實作完成;
但會有幾個不易搞定的問題會卡住,解決過程如下:
相關問題的解決
程式連結自製憑證SSL的問題
Client 端去 Server 端是以 SSL 來確認 ticket 是否有效時,
由於 server 的安全憑證是自行產生的,而會出現:
OpenSSL::SSL::SSLError in XXController#someaction
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
等錯誤訊息。
參閱:http://notetoself.vrensk.com/2008/09/verified-https-in-ruby 的經驗來解決。
此時修改設定檔:
vendor/plugins/rubycas-client/lib/casclient/client.rb
#在任何有:
https.use_ssl = (uri.scheme == 'https')
#的下面一行多加此行:
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
就可避開檢查何處發行憑證單位的問題。
RoR 預設 cookie 的 domain 是設 host1.company.com,
為了改成用同 domain 的 cookie,
在 config/environments/ 的 development.rb 或 production.rb 裡最底下加:
# RoR 2.3.x 之前用這語法
ActionController::Base.session_options[:session_domain] = '.company.com'
# RoR 2.3.x 之這樣才有效
config.action_controller.session = {
:domain => ".company.com"
}
幾年前就想試的心願就此實現了…
為了不會忘記怎麼試成功,趕緊記錄貼上來。
請問client可以用ASP.NET嗎?
可參考:
Integrating CAS Authentication with Forms Authentication in ASP.Net 2.0 (PDF 檔)
裡面有實作的程式碼。
或 這個網址:
http://www.ja-sig.org/wiki/display/CASC/.Net+Cas+Client
裡面的一個 zip 檔,不曉得是否有用?